package concurrent.completationstage;

import static java.lang.Thread.sleep;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import org.testng.annotations.Test;
import util.MathUtil;

public class Completation1 {

    @Test
    public void t1() {
        CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("hello world f1");
            try {
                sleep(1); // TimeUnit.SECONDS.sleep(1)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "result f1";
        });
        CompletableFuture<String> f2 = f1.thenApply(r -> {
            System.out.println(r);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "f2";
        });
        CompletableFuture<String> f3 = f2.thenApply(r -> {
            System.out.println(r);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "f2";
        });

        CompletableFuture<String> f4 = f1.thenApply(r -> {
            System.out.println(r);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "f2";
        });
        CompletableFuture<String> f5 = f4.thenApply(r -> {
            System.out.println(r);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "f2";
        });
        CompletableFuture<String> f6 = f5.thenApply(r -> {
            System.out.println(r);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "f2";
        });
    }

    public static void main(String[] args) throws InterruptedException {
//        t2();
//        Thread.sleep(1000 * 16);

        CompletableFuture.supplyAsync(() -> 12)
            .thenAccept(res -> {

                // 开启一个异步耗时操作。需要验证，外部这个结束了，内层的未必结束
                CompletableFuture.supplyAsync(() ->0)
                    .thenAccept(res2 -> {
                        for (int i = 0; i < 50; i++) {
                            MathUtil.resolvePrime();
                        }
                        System.out.println("res in inner thenCompose finished");
                    });

                System.out.println("res in thenCompose " + res);

            })
            .toCompletableFuture();


    }

    @Test
    private static void t2() {
        // 只声明会怎么样
//        CompletableFuture<String> future = new CompletableFuture<>();

        AtomicBoolean f1 = new AtomicBoolean(false);
        AtomicBoolean f2 = new AtomicBoolean(false);

        Runnable r = () -> {
            for (int i = 0; i < 25; i++) {
                MathUtil.resolvePrime();
            }

            // 运行这个任务的线程是否无法输出内容到控制台？
            System.out.println("task 1 finished");
            f1.set(true);

//            Runnable r2 = () -> {
//                for (int i = 0; i < 25; i++) {
//                    MathUtil.resolvePrime();
//                }
//
//                // 运行这个任务的线程是否无法输出内容到控制台？
//                System.out.println("task 2 finished");
//                f2.set(true);
//            };
//
//            Thread t = new Thread(r2);
//            t.start();
        };

        CompletableFuture.supplyAsync(() -> r);

//        CompletableFuture.supplyAsync(() -> r)
//            .whenComplete((res, exc) -> {
//                System.out.println("res: " + res);
//                System.out.println("exc: " + exc);
//                System.out.println("task 1 and 2 finished");
//                System.out.println(f1 + ", " + f2);
//            });

    }

    @Test
    private void t3() {
        CompletableFuture.supplyAsync(() -> 99)
            .whenComplete((res, ex) -> {
                System.out.println(res);
            });

    }

    @Test
    private void t4() {

        // 如果cancel方法返回true，那么isCancelled方法也返回true
        //            if (future.isCancelled()) {
        //
        //            }
        // 这个判断包括了正常终止、异常、取消
        //            if (future.isDone()) {
        //                return true;
        //            }
    }

    @Test
    private void t5() {


        CompletableFuture.supplyAsync(() -> 12)
            .thenAccept(res -> {

                // 开启一个耗时操作。需要验证，外部这个结束了，内层的未必结束
                CompletableFuture.supplyAsync(() ->0)
                    .thenAccept(res2 -> {
                        for (int i = 0; i < 50; i++) {
                            MathUtil.resolvePrime();
                        }
                        System.out.println("res in inner thenCompose finished");
                    }).toCompletableFuture();

                System.out.println("res in thenCompose " + res);

            })
            .toCompletableFuture();
    }



}
